<template>
  <div class="rulesBox">
    <div class="modelBox">月</div>
    <el-row :gutter="24">
      <el-col :span="12">
        <el-radio-group v-model="state.mouth">
          <el-radio :label="1"><span>每个月</span></el-radio>
          <el-radio :label="2" style="margin-top:24px">
            <span>从</span>
            <el-input-number
              :disabled="state.mouth !== 2"
              v-model="state.mouthBegin"
              :min="1"
              :max="12"
              :step="1"
              :precision="0"
            ></el-input-number>
            <span>月开始，每</span>
            <el-input-number
              :disabled="state.mouth !== 2"
              v-model="state.mouthNum"
              :min="1"
              :max="12"
              :step="1"
              :precision="0"
            ></el-input-number>
            <span>月一次</span>
          </el-radio>
          <el-radio :label="3" style="margin-top:24px">
            <span>指定月份</span>
            <el-select
              style="width:445px;"
              class="selectHeight"
              v-model="state.mouthNo"
              :disabled="state.mouth !== 3"
              multiple
              :popper-append-to-body="false"
            >
              <el-option
                v-for="item in 12"
                :key="'index_' + item"
                :value="item"
                :label="`${item}月`"
              ></el-option>
            </el-select>
          </el-radio>
        </el-radio-group>
      </el-col>
    </el-row>

    <div style="margin:24px 0 12px;">
      <el-dropdown @command="changeType">
        <span class="el-dropdown-link">
          {{ state.type }}<i class="el-icon-arrow-down el-icon--right"></i>
        </span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="周">周</el-dropdown-item>
          <el-dropdown-item command="日">日</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
    <div>
      <el-row :gutter="24" v-if="state.type === '周'">
        <el-col :span="12">
          <el-radio-group v-model="state.week">
            <el-radio :label="1"><span>每周</span></el-radio>
            <el-radio :label="2" style="margin-top:24px">
              <span>从第</span>
              <el-input-number
                :disabled="state.week !== 2"
                v-model="state.weekBegin"
                :min="1"
                :max="5"
                :step="1"
                :precision="0"
              ></el-input-number>
              <span>周的</span>
              <el-select
                class="selectHeight"
                v-model="state.weekNum"
                :disabled="state.week !== 2"
                :popper-append-to-body="false"
              >
                <el-option
                  v-for="item in weekList"
                  :key="'index_' + item.key"
                  :value="item.key"
                  :label="item.title"
                ></el-option>
              </el-select>
            </el-radio>
            <el-radio :label="3" style="margin-top:24px">
              <span>指定星期</span>
              <el-select
                style="width:445px"
                class="selectHeight"
                v-model="state.weekNo"
                :disabled="state.week !== 3"
                multiple
                :popper-append-to-body="false"
              >
                <el-option
                  v-for="item in weekList"
                  :key="'index_' + item.key"
                  :value="item.key"
                  :label="item.title"
                ></el-option>
              </el-select>
            </el-radio>
            <el-radio :label="4" style="margin-top:24px">
              <span>本月最后一个</span>
              <el-select
                class="selectHeight"
                v-model="state.weekLast"
                :disabled="state.week !== 4"
                :popper-append-to-body="false"
              >
                <el-option
                  v-for="item in weekList"
                  :key="'index_' + item.key"
                  :value="item.key"
                  :label="item.title"
                ></el-option>
              </el-select>
            </el-radio>
          </el-radio-group>
        </el-col>
      </el-row>

      <el-row :gutter="24" v-if="state.type === '日'">
        <el-col :span="12">
          <el-radio-group v-model="state.day">
            <el-radio :label="1"><span>每天</span></el-radio>
            <el-radio :label="2" style="margin-top:24px">
              <span>从</span>
              <el-input-number
                v-model="state.dayBegin"
                :disabled="state.day !== 2"
                :min="1"
                :max="31"
                :step="1"
                :precision="0"
              ></el-input-number>
              <span>日的开始， 每</span>
              <el-input-number
                v-model="state.dayNum"
                :disabled="state.day !== 2"
                :min="1"
                :max="31"
                :step="1"
                :precision="0"
              ></el-input-number>
              <span>天一次</span>
            </el-radio>
            <el-radio :label="3" style="margin-top:24px">
              <span>指定日期</span>
              <el-select
                class="selectHeight"
                style="width:445px"
                v-model="state.dayNo"
                :disabled="state.day !== 3"
                multiple
                :popper-append-to-body="false"
              >
                <el-option
                  v-for="item in getNumArr(31, false)"
                  :key="'index_' + item"
                  :value="item"
                  :label="`${item}日`"
                ></el-option>
              </el-select>
            </el-radio>
            <el-radio :label="4" style="margin-top:24px">
              <span>本月最后一个天</span>
            </el-radio>
          </el-radio-group>
        </el-col>
      </el-row>
    </div>

    <div class="modelBox" style="margin-top:24px">时</div>
    <el-row :gutter="24">
      <el-col :span="12">
        <el-radio-group v-model="state.hours">
          <el-radio :label="1"><span>每个小时</span></el-radio>
          <el-radio :label="2" style="margin-top:24px">
            <span>从</span>
            <el-input-number
              v-model="state.hoursBegin"
              :disabled="state.hours !== 2"
              :min="1"
              :max="23"
              :step="1"
              :precision="0"
            ></el-input-number>
            <span>点开始，每</span>
            <el-input-number
              v-model="state.hoursNum"
              :disabled="state.hours !== 2"
              :min="1"
              :max="23"
              :step="1"
              :precision="0"
            ></el-input-number>
            <span>小时一次</span>
          </el-radio>
          <el-radio :label="3" style="margin-top:24px">
            <span>指定时间</span>
            <el-select
              class="selectHeight"
              style="width:445px"
              v-model="state.hoursNo"
              :disabled="state.hours !== 3"
              multiple
              :popper-append-to-body="false"
            >
              <el-option
                v-for="item in getNumArr(24)"
                :key="'index_' + item"
                :value="item"
                :label="`${item}点`"
              ></el-option
            ></el-select>
          </el-radio>
        </el-radio-group>
      </el-col>
    </el-row>

    <div class="modelBox" style="margin-top:24px">分</div>
    <el-row :gutter="24">
      <el-col :span="12">
        <el-radio-group v-model="state.min">
          <el-radio :label="3">
            <span>指定时间</span>
            <el-select
              class="selectHeight"
              style="width:445px"
              v-model="state.minNo"
              :disabled="state.min !== 3"
              multiple
              :popper-append-to-body="false"
            >
              <el-option
                v-for="item in getNumArr(60)"
                :key="'index_' + item"
                :value="item"
                :label="`${item}分`"
              ></el-option
            ></el-select>
          </el-radio>
        </el-radio-group>
      </el-col>
    </el-row>

    <div class="modelBox" style="margin:24px 0 12px">
      循环规则解释
      <span
        style="margin-left:16px;color:var(--primary);font-weight:400;font-size:12px; cursor: pointer;"
        @click="submit(false)"
      >
        刷新
      </span>
    </div>
    <div
      style="color: #666;
    font-weight: 400;
    line-height: 1;
    font-size:12px
    "
    >
      {{ state.cronStr }}
    </div>
  </div>
</template>
<script lang="ts">
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
import cronstrue from "cronstrue/i18n";
import ElementUI from "element-ui";
Vue.use(ElementUI);
interface State {
  /** 数据状态 */
  loading: boolean;
  /** 展示收起左边 */
  visible: boolean;
  /** 月 */
  mouth: number;
  /** 从 第几月*/
  mouthBegin: number;
  /** 没几个月  */
  mouthNum: number;
  /** 指定月  */
  mouthNo: number[] | undefined;

  type: string;

  /** 周 */
  week: number;
  /** 本周最后一个几  */
  weekLast: number;
  /** 从 第几周*/

  weekBegin: number;
  /** 每几个周  */
  weekNum: number;
  /** 指定周  */
  weekNo: number[] | undefined;

  /** 天  */
  day: number;
  /** 本周最后一个几  */
  dayLast: number;
  /** 从 第几月*/
  dayBegin: number;
  /** 每几个月  */
  dayNum: number;
  /** 指定天  */
  dayNo: number[] | undefined;

  /** 时  */
  hours: number;
  /** 从 第几月*/
  hoursBegin: number;
  /** 每几个小时  */
  hoursNum: number;
  /** 指定天  */
  hoursNo: number[] | undefined;
  /** cron */
  cron: string;
  cronStr: string;

  /** 分 */
  min: number;
  minNo: number[] | undefined;
}
@Component
export default class Index extends Vue {
  /**  通用样式 */
  @Prop() visible!: string;
  @Prop() cron?: string | undefined;
  /** 数据 */
  state: State = {
    loading: false,
    visible: false,

    /** 月 */
    mouth: 1,
    /** 从 第几月*/
    mouthBegin: 1,
    /** 每几个月  */
    mouthNum: 1,
    /** 指定月  */
    mouthNo: [],
    type: "周",

    /** 周 */
    week: 1,

    /** 从 第几月*/
    weekBegin: 1,
    /** 每几个月  */
    weekNum: 1,
    /** 指定月  */
    weekNo: [],
    /** 本周最后一个几  */
    weekLast: 1,

    /** 天  */
    day: 1,

    /** 从 第几月*/
    dayBegin: 1,
    /** 每几个月  */
    dayNum: 1,
    /** 指定天  */
    dayNo: [],
    /** 本周最后一个几  */
    dayLast: 1,

    /** 时  */
    hours: 1,
    /** 从 第几月*/
    hoursBegin: 1,
    /** 每几个小时  */
    hoursNum: 1,
    /** 指定小时  */
    hoursNo: [0],

    min: 3,

    minNo: [0],

    /** cron 表达式 */
    cron: "",
    cronStr: "",
  };
  /** 生命周期 */
  changeType(name: string) {
    this.state.type = name;
  }

  submit(type = true) {
    /** 处理月 */
    const minStr = this.getStr("min");
    const monthsStr = this.getStr("mouth");
    const weekStr = this.state.type === "周" ? this.getStr("week") : "?";
    const dayStr = this.state.type === "日" ? this.getStr("day") : "?";
    const hoursStr = this.getStr("hours");
    // cron  秒  分  时  天 月 周
    const cron =
      "0 " +
      minStr +
      " " +
      hoursStr +
      " " +
      dayStr +
      " " +
      monthsStr +
      " " +
      weekStr;
    this.state.cronStr = cronstrue.toString(cron, {
      locale: "zh_CN",
      dayOfWeekStartIndexZero: true,
    });
    this.state.cron = cron;
    if (type) {
      this.$emit("callback", {
        value: this.state.cron,
        name: this.state.cronStr,
      });
    }
  }
  /** 获取选择数字数组 */
  getNumArr(num: number, addZero = true) {
    const numArr: number[] = [];
    for (let index = 0; index < num; index++) {
      if (addZero) {
        numArr.push(index);
      }
      if (!addZero) {
        numArr.push(index + 1);
      }
    }
    return numArr;
  }
  /** 合并数据 */
  getStr(key: any) {
    let newStr = "";
    if ((this.state as any)[key] === 1) {
      newStr = "*";
    }
    if ((this.state as any)[key] === 2) {
      if (key === "week") {
        // 周的数据显示 反过来
        newStr =
          (this.state as any)[key + "Num"] +
          "#" +
          (this.state as any)[key + "Begin"];
      } else {
        newStr =
          (this.state as any)[key + "Begin"] +
          "/" +
          (this.state as any)[key + "Num"];
      }
    }
    if ((this.state as any)[key] === 3) {
      newStr = (this.state as any)[key + "No"].toString();
    }
    if ((this.state as any)[key] === 4) {
      newStr =
        ((this.state as any)[key + "Last"]
          ? (this.state as any)[key + "Last"].toString()
          : "") + "L";
    }
    return newStr;
  }
  /** 解析数据 */
  splitData() {
    this.setData("min", 1);
    this.setData("hours", 2);
    this.setData("day", 3);
    this.setData("mouth", 4);
    this.setData("week", 5);
  }
  setData(key: string, num: number) {
    const list = this.state.cron.split(" ");
    const str = list[num];
    if (str === "?" && key == "week") {
      this.state.type = "日";
    }
    if (str === "?" && key == "day") {
      this.state.type = "周";
    }
    if (str === "*") {
      /** 每个月 每周 每天 每小时  */
      (this.state as any)[key] = 1;
      this.$forceUpdate();
    }
    if (str.includes("#")) {
      /** 周---指定时间长度  */
      (this.state as any)[key] = 2;
      const newStr = str.split("#").map((item) => Number(item));
      (this.state as any)[key + "Num"] = newStr[0];
      (this.state as any)[key + "Begin"] = newStr[1];
      this.$forceUpdate();
    }
    if (str.includes("/")) {
      /** 其他（月 日 小时）---指定时间长度  */
      (this.state as any)[key] = 2;
      const newStr = str.split("/").map((item) => Number(item));
      (this.state as any)[key + "Begin"] = newStr[0];
      (this.state as any)[key + "Num"] = newStr[1];
      this.$forceUpdate();
    }
    if (
      str.includes(",") ||
      (str != "*" &&
        !str.includes("#") &&
        !str.includes("/") &&
        !str.includes("L") &&
        !str.includes("?"))
    ) {
      /** 其他（月 日 小时）---勾选时间  */
      (this.state as any)[key] = 3;
      (this.state as any)[key + "No"] = str
        .split(",")
        .map((item) => Number(item));
      this.$forceUpdate();
    }
    if (str.includes("L")) {
      (this.state as any)[key] = 4;
      const newStr = str.split("L").map((item) => Number(item));
      newStr.length > 1 ? ((this.state as any)[key + "Last"] = newStr[1]) : "";
      this.$forceUpdate();
    }
    // if(!isNaN(str)){

    // }
  }

  /** 关闭 */
  cancel() {
    this.$emit("callback", false);
  }

  @Watch("cron", { immediate: true })
  OnCronData(val: string | undefined) {
    if (val) {
      this.state.cron = val;
      this.splitData();
      this.state.cronStr = cronstrue.toString(val, {
        locale: "zh_CN",
        dayOfWeekStartIndexZero: false,
      });
    }
  }
  get weekList() {
    return [
      {
        key: 1,
        title: "星期一",
      },
      {
        key: 2,
        title: "星期二",
      },
      {
        key: 3,
        title: "星期三",
      },
      {
        key: 4,
        title: "星期四",
      },
      {
        key: 5,
        title: "星期五",
      },
      {
        key: 6,
        title: "星期六",
      },
      {
        key: 7,
        title: "星期日",
      },
    ];
  }
}
</script>
<style>
@import url("/publicData/styles/theme/fonts/element-icons.woff");
@import url("/publicData/styles/theme/index.css");
</style>
<style lang="scss">
.rulesBox {
  .el-dropdown-link {
    font-style: normal;
    font-weight: 700;
    font-size: 14px;
    line-height: 18px;
    color: #333333;
  }
  .el-radio {
    display: block !important;
  }
}
</style>
<style lang="scss" scoped>
.selectHeight {
  height: 34px;
}
.rulesBox {
  span {
    margin: 0 4px;
  }
}
.modelBox {
  font-style: normal;
  font-weight: 700;
  font-size: 14px;
  line-height: 18px;
  color: #333333;
  margin-bottom: 12px;
}

.longTime {
  display: flex;
  align-items: center;
  text-align: center;
  margin-top: 4px;
  input {
    min-width: 60px;
    border: 1px solid #ddd;
    line-height: 32px;
    padding: 0 12px;
    box-sizing: border-box;
    border-radius: 4px;
    text-align: center;
    &:focus {
      outline: none;
    }
  }
  span {
    display: inline-block;
    width: 30px;
  }
}
</style>
